This code was automatically extracted from a .lhs file that
uses the following convention:

-- lines beginning with ">" are executable
-- lines beginning with "<" are in the text,
     but not necessarily executable
-- lines beginning with "|" are also in the text,
     but are often just expressions or code fragments.

> class Functor f where
>   fmap :: (a -> b) -> f a -> f b

> instance Functor Tree where
>   fmap f (Leaf x)       = Leaf   (f x)
>   fmap f (Branch t1 t2) = Branch (fmap f t1) (fmap f t2)

> instance Functor Tree where
>   fmap = mapTree

> instance Functor [] where
>   fmap f []     = []
>   fmap f (x:xs) = f x : fmap f xs

> instance Functor [] where
>   fmap = map

| fmap id = id
| fmap (f . g) = fmap f . fmap g

> class  Monad m  where
>     (>>=)            :: m a -> (a -> m b) -> m b
>     (>>)             :: m a -> m b -> m b
>     return           :: a -> m a
>     fail             :: String -> m a
>
>     m >> k           =  m >>= \_ -> k
>     fail s           = error s

> do e ==> e

| do e1; e2; ...; en
| ==> e1 >> do e2 ; ...; en

| do writeFile "testFile.txt" "Hello File System"
|    putStr "Hello World"

| writeFile "testFile.txt" "Hello File System" >>
| putStr "Hello World"

> (>>) :: Monad m => m a -> m b -> m b

> (>>) :: IO () -> IO () -> IO ()

> do pat <- e1 ; e2 ; ...; en
> ==> let ok pat = do e2 ; ...; en
>         ok _   = fail "..."
>     in e1 >>= ok 

> do x <- e1 ; e2 ; ...; en
> ==> e1 >>= \x -> do e2 ; ...; en

> do let decllist ; e2 ; ...; en
> ==> let decllist in do e2 ; ...; en

< return a >>= k           = k a
< m >>= return             = m
< m >>= (\x -> k x >>= h)  = (m >>= k) >>= h

< m1 >> (m2 >> m3)  = (m1 >> m2) >> m3

< fmap f xs = xs >>= return . f

< fmap f xs                  = do x <- xs ; return (f x)

< do x <- return a ; k x     =  k a
< do x <- m ; return x       =  m
< do x <- m ; y <- k x ; h y = do y <- (do x <- m ; k x) ; h y
< do m1 ; m2 ; m3            = do (do m1 ; m2) ; m3

| do k <- getKey w
|    return k

< do k <- getKey w
<    n <- changeKey k
<    respond n

| let keyStuff = do k <- getKey w
|                   changeKey k
| in do n <- keyStuff
|       respond n

> instance  Monad Maybe  where
>     Just x  >>= k   =  k x
>     Nothing >>= k   =  Nothing
>     return          =  Just
>     fail s          =  Nothing

> instance  Functor Maybe  where
>     fmap f Nothing    =  Nothing
>     fmap f (Just x)   =  Just (f x)

| (>>=)  :: Maybe a -> (a -> Maybe b) -> Maybe b
| return :: a -> Maybe a

| g (f x)

| case (f x) of 
|   Nothing -> Nothing
|   Just y  -> case (g y) of
|                Nothing -> Nothing
|                Just z  -> z

| f x >>= \y ->
| g y >>= \z ->
| return z

| do y <- f x
|    z <- g y
|    return z

| f x >>= \y ->
| g y >>= \z ->
| return z
| ==> { <<< currying simplification >>> }
| f x >>= \y ->
| g y >>= return 
| ==> { <<< monad law for >>> return <<< >>> }
| f x >>= \y ->
| g y
| ==> { <<< currying simplification >>> }
| f x >>= g

> composeM :: Monad m => (b -> m c) -> (a -> m b) -> (a -> m c)
> (g `composeM` f) x = f x >>= g

> instance  Monad []  where
>     m >>= k          =  concat (map k m)
>     return x         =  [x]
>     fail x           =  [ ]

< concat :: [[a]] -> [a]
< concat xss = foldr (++) [] xss

| (>>=)  :: [a] -> (b -> [b]) -> [b]
| return :: a -> [a]

| do x <- [1,2,3]
|    y <- [4,5,6]
|    return (x,y)

| [(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]

| [(x,y) | x <- [1,2,3], y <- [4,5,6]]

< do x <- xs ; return (f x)

< [ f x | x <- xs ]

< fmap f xs = do x <- xs ; return (f x)

< data Id a = Id a

< putStr  :: String -> IO ()
< putStr s = sequence_ (map putChar s)

< putStr  :: String -> IO ()
< putStr s = mapM_ putChar s

< sequence       :: Monad m => [m a] -> m [a] 
< sequence       =  foldr mcons (return [])
<                     where mcons p q = do x  <- p
<                                          xs <- q
<                                          return (x:xs)

< sequence_      :: Monad m => [m a] -> m () 
< sequence_      =  foldr (>>) (return ())

< mapM             :: Monad m => (a -> m b) -> [a] -> m [b]
< mapM f as        =  sequence (map f as)

< mapM_            :: Monad m => (a -> m b) -> [a] -> m ()
< mapM_ f as       =  sequence_ (map f as)

< (=<<)            :: Monad m => (a -> m b) -> m a -> m b
< f =<< x          =  x >>= f

> class  Monad m => MonadPlus m  where
>      mzero  :: m a
>      mplus  :: m a -> m a -> m a

< m >>= (\x -> mzero) = mzero
< mzero >>= m         = mzero

> m `mplus` mzero = m
> mzero `mplus` m = m

> instance  MonadPlus Maybe  where
>     mzero                 = Nothing
>     Nothing `mplus` ys    = ys
>     xs      `mplus` ys    = xs

> instance  MonadPlus []  where
>     mzero = []
>     mplus = (++)

> data SM a = SM (S -> (S,a))

> instance Monad SM where
>   return a    
>     = SM (\s -> (s,a))
>   SM sm0 >>= fsm1
>     = SM $ \s0 ->
>         let (s1,a1) =  sm0 s0
>             SM sm1  = fsm1 a1
>             (s2,a2) =  sm1 s1
>         in (s2,a2)

> data Tree a = Leaf a | Branch (Tree a) (Tree a)
>      deriving Show

> test = let t = Branch (Leaf 'a') (Leaf 'b')
>        in label (Branch t t)

| Branch (Branch (Leaf 0) (Leaf 1)) 
|        (Branch (Leaf 2) (Leaf 3))

> label :: Tree a -> Tree Integer
> label t = snd (lab t 0)

> lab :: Tree a -> Integer -> (Integer, Tree Integer)
> lab (Leaf a) n 
>     = (n+1, Leaf n)
> lab (Branch t1 t2) n
>     = let (n1,t1') = lab t1  n
>           (n2,t2') = lab t2 n1
>       in  (n2, Branch t1' t2')

> newtype Label a = Label (Integer -> (Integer,a))

> instance Monad Label where
>   return a         
>     = Label (\s -> (s,a))
>   Label lt0 >>= flt1
>     = Label $ \s0 ->
>         let (s1,a1)   = lt0 s0
>             Label lt1 = flt1 a1
>         in lt1 s1

> mlabel :: Tree a -> Tree Integer
> mlabel t = let Label lt = mlab t
>            in snd (lt 0)

> mlab :: Tree a -> Label (Tree Integer)
> mlab (Leaf a)
>      = do n <- getLabel
>           return (Leaf n)
> mlab (Branch t1 t2)
>      = do t1' <- mlab t1
>           t2' <- mlab t2
>           return (Branch t1' t2')

> getLabel :: Label Integer
> getLabel = Label (\n -> (n+1,n))

> mtest = let t = Branch (Leaf 'a') (Leaf 'b')
>         in mlabel (Branch t t)

> instance Functor Int where ...

> instance Functor (Tree Int) where ...

